<?php
//生成验证码

use Illuminate\Support\Facades\Log;

function randomkeys()
{
    return rand(100000, 999999);
}

//生成uuid
function makeUuid($length)
{
    $pattern = '1234567890abcdefghijklmnopqrstuvwxyz
               ABCDEFGHIJKLOMNOPQRSTUVWXYZ';
    $key = '';
    for ($i = 0; $i < $length; $i++) {
        $key .= $pattern{mt_rand(0, 35)};    //生成php随机数
    }
    return $key;
}

//生成随机唯一token
function getRoundToken()
{
    $token = md5(uniqid(md5(microtime(true)), true));
    return $token;
}

/*
//从cookie中获取token
function getTokenFCookie(){
    if(isset($_COOKIE['user_token'])){
        return $_COOKIE['user_token'];
    }else{
        return '';
    }
}
*/


function init_redis_session()
{
    ini_set("session.save_handler", "redis");
    ini_set("session.save_path", sprintf("tcp://%s:%s?database=%s", env('REDIS_HOST'), env('REDIS_PORT'), env('REDIS_SESSION_DB')));
    session_start();
}

//写入日志 todo
function write_log($dirName, $request_desc = 'log', $requestData)
{
    $dirPath = storage_path() . '/apiLogs';
    if (!is_dir($dirPath)) {
        mkdir($dirPath, 0777, true);
        chmod($dirPath, 0777);
    }
    if (is_array($requestData)) {
        file_put_contents($dirPath . '/' . $dirName . '-' . date('Y-m-d') . '.log', '[' . date('Y-m-d H:i:s') . ']' . ' ' . $request_desc . ' ' . json_encode($requestData, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
    } else {
        file_put_contents($dirPath . '/' . $dirName . '-' . date('Y-m-d') . '.log', '[' . date('Y-m-d H:i:s') . ']' . ' ' . $request_desc . ' ' . json_encode($requestData, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
    }

}

//返回当前时间
function date_ymd($timestamp = '')
{
    if ($timestamp) return date('Y-m-d H:i:s', $timestamp);
    return date('Y-m-d H:i:s');
}

/**
 * 发起 server 请求
 * @param $action
 * @param $params
 * @param $httpHeader
 * @return mixed
 */
function curl_request($action, $params, $contentType = 'urlencoded', $httpMethod = 'POST')
{

    $httpHeader = [];
    $ch = curl_init();
    if ($httpMethod == 'POST' && $contentType == 'urlencoded') {
        $httpHeader[] = 'Content-Type:application/x-www-form-urlencoded';
        curl_setopt($ch, CURLOPT_POSTFIELDS, build_query($params));
    }
    if ($httpMethod == 'POST' && $contentType == 'json') {
        $httpHeader[] = 'Content-Type:application/json';
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
    }
    if ($httpMethod == 'GET' && $contentType == 'urlencoded') {
        $action .= strpos($action, '?') === false ? '?' : '&';
        $action .= build_query($params);
    }
    curl_setopt($ch, CURLOPT_URL, $action);
    curl_setopt($ch, CURLOPT_POST, $httpMethod == 'POST');
    curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //处理http证书问题
    curl_setopt($ch, CURLOPT_USERAGENT, "user-agent:kkaudio;;;;;700035");//活动注册信息
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $ret = curl_exec($ch);
    if (false === $ret) {
        $ret = curl_errno($ch);
    }
    curl_close($ch);
    return $ret;
}

/**
 * 重写实现 http_build_query 提交实现(同名key)key=val1&key=val2
 * @param array $formData 数据数组
 * @param string $numericPrefix 数字索引时附加的Key前缀
 * @param string $argSeparator 参数分隔符(默认为&)
 * @param string $prefixKey Key 数组参数，实现同名方式调用接口
 * @return string
 */
function build_query($formData, $numericPrefix = '', $argSeparator = '&', $prefixKey = '')
{
    $str = '';
    if (empty($formData)) {
        return $str;
    }
    foreach ($formData as $key => $val) {
        if (!is_array($val)) {
            $str .= $argSeparator;
            if ($prefixKey === '') {
                if (is_int($key)) {
                    $str .= $numericPrefix;
                }
                $str .= urlencode($key) . '=' . urlencode($val);
            } else {
                $str .= urlencode($prefixKey) . '=' . urlencode($val);
            }
        } else {
            if ($prefixKey == '') {
                $prefixKey .= $key;
            }
            if (isset($val[0]) && is_array($val[0])) {
                $arr = array();
                $arr[$key] = $val[0];
                $str .= $argSeparator . http_build_query($arr);
            } else {
                $str .= $argSeparator . build_query($val, $numericPrefix, $argSeparator, $prefixKey);
            }
            $prefixKey = '';
        }
    }
    return substr($str, strlen($argSeparator));
}

//判断redis 锁是否存在
function check_redis_lock($key)
{
    $lockKey = 'lock:' . $key;
    return \Illuminate\Support\Facades\Redis::EXISTS($lockKey);
}


//Redis 锁 type 1:手动解锁 2：超时解锁
function redis_lock($key, $lockExpire = 10)
{
    $lockKey = 'lock:' . $key;

    $lockValue = time() + $lockExpire;

    $ret = \Illuminate\Support\Facades\Redis::setnx($lockKey, $lockValue);
    if (!$ret) {
        return false;
    }
    \Illuminate\Support\Facades\Redis::expire($lockKey, $lockExpire);
    return true;

}

//Redis 解锁
function redis_unlock($key)
{
    $lockKey = 'lock:' . $key;
    $ret = \Illuminate\Support\Facades\Redis::del($lockKey);
    return $ret;
}

//充值订单号
function create_recharge_order_sn()
{
    return date('ymdhis') . date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
}

//根据经纬度和半径计算出范围
function calcScope($lat, $lng, $radius)
{
    $degree = (24901 * 1609) / 360.0;
    $dpmLat = 1 / $degree;

    $radiusLat = $dpmLat * $radius;//m
    $minLat = $lat - $radiusLat;
    $maxLat = $lat + $radiusLat;

    $mpdLng = $degree * cos($lat * (M_PI / 180));
    $dpmLng = 1 / $mpdLng;
    $radiusLng = $dpmLng * $radius;
    $minLng = $lng - $radiusLng;
    $maxLng = $lng + $radiusLng;

    $scope = array(
        'minLat' => $minLat,
        'maxLat' => $maxLat,
        'minLng' => $minLng,
        'maxLng' => $maxLng
    );
    return $scope;
}

//获取两个经纬度之间的距离
function calcDistance($lat1, $lng1, $lat2, $lng2)
{
    $lat1 = doubleval($lat1);
    $lng1 = doubleval($lng1);
    $lat2 = doubleval($lat2);
    $lng2 = doubleval($lng2);

    $theta = $lng1 - $lng2;
    $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
    $dist = acos($dist);
    $dist = rad2deg($dist);
    $miles = $dist * 60 * 1.1515;
    return ($miles * 1.609344);//km
}

/**
 * 生成可访问的image url
 * @param $image
 * @return string
 */
function build_image($image)
{
    if (empty($image)) {
        return "";
    }

    if (strtolower(substr($image, 0, 4)) == "http") {
        return $image;
    }
    return env('APP_PIC_DOMAIN') . $image;
}


function hide_string($str, $top_len = 3, $tail_len = 4)
{
    if (empty($str)) {
        return "";
    }
    $len = mb_strlen($str);
    $tmp = mb_substr($str, 0, $top_len);
    $tmp1 = mb_substr($str, $len - $tail_len, $tail_len);
    $tmp2 = '';
    for ($i = 0; $i < $len - $top_len - $tail_len; $i++) {
        $tmp2 = $tmp2 . '*';
    }
    $str = $tmp . $tmp2 . $tmp1;
    return $str;
}

/**
 * 获取客户端IP
 * @return string
 */
function client_ip()
{
    if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
        $ip = getenv('HTTP_CLIENT_IP');
    } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
        $ip = getenv('HTTP_X_FORWARDED_FOR');
    } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
        $ip = getenv('REMOTE_ADDR');
    } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    $res = preg_match('/[\d\.]{7,15}/', $ip, $matches) ? $matches [0] : '';
    return $res;
}

/**
 * @param $user_id
 * @return string
 */
function createCode(int $user_id)
{
    $user_id += 45000;
    static $source_string = 'E5FCDG3HQA4B1NOPIJ2RSTUV67MWX89KLYZ';
    $num = $user_id;
    $code = '';
    while ($num > 0) {
        $mod = $num % 35;
        $num = ($num - $mod) / 35;
        $code = $source_string[$mod] . $code;
    }
    if (empty($code[3]))
        $code = str_pad($code, 4, '0', STR_PAD_LEFT);
    return $code;
}

/**
 * @param $code
 * @return float|int
 */
function decode(string $code)
{
    static $source_string = 'E5FCDG3HQA4B1NOPIJ2RSTUV67MWX89KLYZ';
    if (strrpos($code, '0') !== false)
        $code = substr($code, strrpos($code, '0') + 1);
    $len = strlen($code);
    $code = strrev($code);
    $num = 0;
    for ($i = 0; $i < $len; $i++) {
        $num += strpos($source_string, $code[$i]) * pow(35, $i);
    }
    $num -= 45000;
    return $num;
}

function get_remote_addr()
{
    $ip = "unknown";
    if (getenv("HTTP_CLIENT_IP")) {
        $ip = getenv("HTTP_CLIENT_IP");
    } elseif (getenv("HTTP_X_FORWARDED_FOR")) {
        $ip = getenv("HTTP_X_FORWARDED_FOR");
    } elseif (getenv("REMOTE_ADDR")) {
        $ip = getenv("REMOTE_ADDR");
    }
    return $ip;
}


/**
 * 按几率返回数组下标
 * @param $pdf [0.1,0.2,0.3,0.4] 精度到小数后4位, 并且和要为1.0
 * @return int
 */
function aliasMethodRand($pdf)
{
    $d = $pdf;
    $sum = array_sum($d);
    if ($sum != 1.0) {
        return null;
    }
    $multiple = 10000;
    $inc = 0;
    $rand = mt_rand(1, $multiple * $sum);
    foreach ($d as $k => $v) {
        $d[$k] = $inc + $d[$k] * $multiple;
        if ($rand <= $d[$k]) {
            return $k;
        }
        $inc = $d[$k];
    }
    return null;
}


function filterUUID($subject)
{
    if (!preg_match("/^\d*$/", $subject)) return false;
    // *AAA*
    if (preg_match("/^\d*?(\d)\\1\\1\d*?$/", $subject)) return true;

    // *[66|77|88|99] 尾号
    if (preg_match("/^\d*?(66|77|88|99)$/", $subject)) return true;

    // *AABB*
    if (preg_match("/^\d*?(\d)\\1(?!\\1)(\d)\\2\d*?$/", $subject)) return true;

    // *ABAB*
    if (preg_match("/^\d*((\d)(?!\\1)(\d))\\1\d*$/", $subject, $matches)) return true;

    // *ABC*
    if (preg_match("/^\d*?(123|234|345|456|567|678|789|987|876|765|654|543|432|321)\d*?$/", $subject)) return true;

    // *ABCABC*
//        if(preg_match("/^\d*?((\d)(?!\\1)(\d)(?!\\2)(\d))\\1\d*?$/", $subject)) return true;
    if (preg_match("/^\d*?((\d)(\d)(\d))\\1\d*?$/", $subject)) return true;

    // *ABCDABCD*
    if (preg_match("/^\d*?((\d)(\d)(\d)(\d))\\1\d*?$/", $subject)) return true;

    // *[1314|520|521|168|518|918]*
    if (preg_match("/^\d*?(1314|520|521|168|518|918)\d*?$/", $subject)) return true;

    // 四位生日未号
    if (preg_match("/^\d*?((0[1,2,3,4,5,6,7,8,9]|10|11|12)([0,1,2]\d|30|31|32))$/", $subject)) return true;

    // 年开头
    if (preg_match("/^(20[0,1,2,3]\d)\d*?$/", $subject)) return true;

    // 年结尾
    if (preg_match("/^\d*?(20[0,1,2,3]\d)$/", $subject)) return true;

    return false;
}

/**
 * CURL请求 GET/POST
 * */
function curlRequest($url, $data = null, $body = false, $header = [])
{
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);

    if (!empty($header)) {
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    }

    if (!empty($data)) {
        $hadFile = false;
        if (is_array($data) && isset($data['media'])) {
            /**
             * 支持文件上传
             */
            if (class_exists('\CURLFile')) {
                curl_setopt($curl, CURLOPT_SAFE_UPLOAD, true);
                foreach ($data as $key => $value) {
                    if (isPostHasFile($value)) {
                        $data[$key] = new \CURLFile(realpath(ltrim($value, '@')));
                        $hadFile = true;
                    }
                }
            }
            /*elseif (defined('CURLOPT_SAFE_UPLOAD')) {
                if (isPostHasFile()) {
                    curl_setopt($curl, CURLOPT_SAFE_UPLOAD, false);
                    $hadFile = true;
                }
            }*/
        }
        $data = (!$hadFile && is_array($data)) ? http_build_query($data) : $data;

        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    }

    if ($body) {
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_NOBODY, 0);// 只取body
    }

    curl_setopt($curl, CURLOPT_TIMEOUT, 30);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($curl);
    $httpInfo = curl_getinfo($curl);
    curl_close($curl);

    if ($body) {
        return [
            'body' => $output,
            'header' => $httpInfo,
        ];
    } else {
        return $output;
    }
}

/**
 * CURL 检测文件是否存在
 * */
function isPostHasFile($value)
{
    if (is_string($value) && strpos($value, '@') === 0 && is_file(realpath(ltrim($value, '@')))) {
        return true;
    }
    return false;
}


